home *** CD-ROM | disk | FTP | other *** search
- ;Blitz Botz
-
- WBStartup:DEFTYPE.w
-
- #BOT_MAX=3 ;number of bots
- #CYCLE_MAX=1000 ;number of calls each bot gets
- #GRID_HEIGHT=17 ;height of grid must be odd, and over 2
- #GRID_WIDTH=31 ;width of grid must be odd, and over 2
- #GRID_COMPLEX=8 ;30 is least, 1 is most complex
- #GRID_EMPTY=5 ;how empty is the grid??
-
- #GRID_SIZE=#GRID_WIDTH*#GRID_HEIGHT
- #TABLE_LIMIT=(#GRID_WIDTH/2)*(#GRID_HEIGHT/2)
-
- NEWTYPE .botstats
- xpos.w:ypos:dir:bottype
- shotx.w:shoty:shotdir
- time.l:shots
- moved.w
- End NEWTYPE
-
- Dim List stats.botstats(0)
- Dim GRID.w(0,0)
- Dim hits(0,0)
-
- Function.w BOT_FIRE{}
- SHARED stats.botstats()
- USEPATH stats()
- If \shotx=-1
- \shotdir=\dir:\shotx=\xpos:\shoty=\ypos:\shots=\shots+1
- Function Return True
- Else
- Function Return False
- EndIf
- End Function
-
- Function.w BOT_FORWARD{}
- SHARED GRID(),stats.botstats()
- USEPATH stats()
- ; Locate 0,0:Print "X=",\xpos," Y=",\ypos," "
- If \moved=0
- newx.w=\xpos:newy.w=\ypos
- Select \dir
- Case 0:newy=newy-1
- Case 1:newx=newx+1
- Case 2:newy=newy+1
- Case 3:newx=newx-1
- End Select
- If GRID(newx,newy)<16
- \moved=1:GRID(\xpos,\ypos)=GRID(\xpos,\ypos)&$FDF:GRID(newx,newy)=GRID(newx,newy)|32
- \xpos=newx:\ypos=newy
- Function Return True
- Else
- Function Return False
- EndIf
- Else
- Function Return False
- EndIf
- End Function
-
- Function.w BOT_TURNCW{}
- ;returns what you can see in the square ahead (that you've just turned too - clockwise)
- SHARED GRID.w(),stats.botstats()
- USEPATH stats()
- \dir=\dir+1:If \dir=4 Then \dir=0
- Select \dir
- Case 0:tmp=GRID(\xpos,\ypos-1)
- Case 1:tmp=GRID(\xpos+1,\ypos)
- Case 2:tmp=GRID(\xpos,\ypos+1)
- Case 3:tmp=GRID(\xpos-1,\ypos)
- End Select
- Function Return tmp
- End Function
-
- Function.w BOT_TURNAC{}
- ;returns what you can see in the square ahead (that you've just turned too - anti clockwise)
- SHARED GRID.w(),stats.botstats()
- USEPATH stats()
- \dir=\dir-1:If \dir=-1 Then \dir=3
- Select \dir
- Case 0:tmp=GRID(\xpos,\ypos-1)
- Case 1:tmp=GRID(\xpos+1,\ypos)
- Case 2:tmp=GRID(\xpos,\ypos+1)
- Case 3:tmp=GRID(\xpos-1,\ypos)
- End Select
- Function Return tmp
- End Function
-
- Function.w BOT_LOOK{squares.w}
- SHARED GRID.w(),stats.botstats()
- USEPATH stats()
- ;look squares ahead of the bot
- newx=\xpos:newy=\ypos:tmp=-1
- Select \dir
- Case 0:newy=newy-squares
- Case 1:newx=newx+squares
- Case 2:newy=newy+squares
- Case 3:newx=newx-squares
- End Select
- If (newx>-1)&(newx<#GRID_WIDTH)
- If (newy>-1)&(newy<#GRID_HEIGHT)
- tmp=GRID(newx,newy)
- EndIf
- EndIf
- Function Return tmp
- End Function
-
- Statement UPDATE_SHOTS{}
- SHARED GRID(),hits(),stats.botstats()
- ResetList stats():USEPATH stats()
- While NextItem(stats())
- If \shotx<>-1
- newx=\shotx:newy=\shoty:GRID(newx,newy)=GRID(newx,newy)&$FFE
- Select GRID(newx,newy)&$FF0
- Case 32 ;hit bot...find bot then kill shot
- If (\xpos<>newx)|(\ypos<>newy)
- PushItem stats():shothit=0:ResetList stats()
- While (NextItem(stats()))&(shothit=0)
- If (\xpos=newx)&(\ypos=newy) Then shothit=\bottype
- Wend
- PopItem stats()
- hits(\bottype,shothit)=hits(\bottype,shothit)+1:newx=-1
- EndIf
- Case 256:newx=-1
- End Select
- If newx<>-1
- Select \shotdir
- Case 0:newy=newy-1
- Case 1:newx=newx+1
- Case 2:newy=newy+1
- Case 3:newx=newx-1
- End Select
- Select GRID(newx,newy)&$FF0
- Case 32 ;hit bot...find bot then kill shot
- If (\xpos<>newx)|(\ypos<>newy)
- PushItem stats():shothit=0:ResetList stats()
- While (NextItem(stats()))&(shothit=0)
- If (\xpos=newx)&(\ypos=newy) Then shothit=\bottype
- Wend
- PopItem stats()
- hits(\bottype,shothit)=hits(\bottype,shothit)+1:newx=-1
- EndIf
- Case 256:newx=-1
- End Select
- EndIf
- \shotx=newx:\shoty=newy
- EndIf
- Wend
- ;now draw them all into the grid
- ResetList stats()
- While NextItem(stats())
- If \shotx<>-1 Then GRID(\shotx,\shoty)=GRID(\shotx,\shoty)|1
- Wend
- End Statement
-
- Statement Gerbil{}
- If Rnd(100)>69
- If BOT_TURNAC{}<>0
- nil=BOT_TURNAC{}
- If BOT_TURNAC{}<>0
- If BOT_TURNAC{}=0 Then nil=BOT_FORWARD{} Else nil=BOT_TURNAC{}
- EndIf
- EndIf
- EndIf
- nil=BOT_FORWARD{}
- If Rnd(100)>49
- nil=BOT_TURNCW{}:nil=BOT_TURNCW{}
- nil=BOT_FIRE{}
- nil=BOT_TURNAC{}:nil=BOT_TURNAC{}
- EndIf
- End Statement
-
- Statement Gophor{}
- If Peek.l(?Gophor_Flag)=0
- If (Rnd(100)>69)|(BOT_FORWARD{}=False)
- If BOT_TURNAC{}<>0
- nil=BOT_TURNAC{}
- If BOT_TURNAC{}<>0
- If BOT_TURNAC{}<>0 Then nil=BOT_TURNAC{}
- EndIf
- EndIf
- EndIf
- tmp=0
- While (BOT_TURNAC{}&32=0)&(tmp<3)
- tmp+1
- Wend
- If (tmp<3)|(BOT_LOOK{1}&32=32) Then Poke.l ?Gophor_Flag,1 ;we've found bot, so stick with it
- Else
- nil=BOT_FORWARD{}
- If BOT_LOOK{1}&32=0
- tmp=0
- While (BOT_TURNAC{}&32=0)&(tmp<3)
- tmp+1
- Wend
- If tmp=3 Then Poke.l ?Gophor_Flag,0 ;go back to random searching if somehow lost bot
- EndIf
- nil=BOT_FIRE{}
- EndIf
- Goto Gophor_Skip
- Gophor_Flag: Dc.l 0
- Gophor_Skip:
- End Statement
-
- Statement Hamster{}
- If BOT_FORWARD{}=False
- If Rnd(3)>0 Then nil=BOT_TURNAC{} Else nil=BOT_TURNCW{}
- Else
- nil=BOT_FIRE{}
- EndIf
- End Statement
-
- If NTSC Then vsize.w=60 Else vsize.w=50
-
- Gosub INIT_DISPLAY
-
- Gosub MAKE_GRID:Gosub INIT_BOTS
-
- ResetTimer:cycles.l=0
-
- Repeat
- ResetList stats():USEPATH stats()
- While NextItem(stats())
- \moved=0:timestart.l=Ticks
-
- Select \bottype ;add your bots here
- Case 1:Gerbil{}
- Case 2:Gophor{}
- Case 3:Hamster{}
- End Select
-
- timenew.l+(Ticks-timestart):\time=\time+timenew
- Wend
- UPDATE_SHOTS{} ;:VWait
- Gosub SHOW_GRID
- cycles+1
- Until cycles=#CYCLE_MAX
-
- Gosub SHOW_STATS
-
- MouseWait
-
- End
-
- INIT_BOTS:
- ;randomize startup positions, and order
- Dim List stats.botstats(#BOT_MAX-1)
- Dim hits(#BOT_MAX,#BOT_MAX)
- Dim order(#BOT_MAX-1)
- For loop=1 To #BOT_MAX:order(loop-1)=loop:Next loop
- For loop=1 To 100
- Exchange order(Rnd(#BOT_MAX)),order(Rnd(#BOT_MAX))
- Next loop
- ClearList stats():USEPATH stats()
- For loop=1 To #BOT_MAX
- If AddItem(stats())
- \bottype=order(loop-1):\dir=Rnd(4):\time=0:\moved=0:\shotx=-1:\shoty=0:\shotdir=0
- posokay=False
- While posokay=False
- \xpos=Rnd(#GRID_WIDTH):\ypos=Rnd(#GRID_HEIGHT)
- If GRID(\xpos,\ypos)=0 Then posokay=True:GRID(\xpos,\ypos)=32
- Wend
- EndIf
- Next loop
- Return
-
- MAKE_GRID:
- ;generate the grid
- Dim GRID.w(#GRID_WIDTH-1,#GRID_HEIGHT-1)
- Dim TABLE(#TABLE_LIMIT-1,1)
- For xloop=0 To #GRID_WIDTH-1
- For yloop=0 To #GRID_HEIGHT-1
- If (xloop&1)AND(yloop&1) Then GRID(xloop,yloop)=0 Else GRID(xloop,yloop)=1
- Next yloop
- Next xloop
- Gosub MAKE_PATH
- tablemax=0
- For xloop=0 To #GRID_WIDTH-1
- For yloop=0 To #GRID_HEIGHT-1
- If (xloop&1)AND(yloop&1)
- If GRID(xloop,yloop)=2 Then TABLE(tablemax,0)=xloop:TABLE(tablemax,1)=yloop:tablemax+1
- End If
- Next yloop
- Next xloop
- ;now jumble all used positions (COMPLEX NUMBER OF TIMES)
- For loop=0 To #GRID_COMPLEX
- For loop1=0 To tablemax-1
- newpos=Rnd(tablemax):Exchange TABLE(loop1,0),TABLE(newpos,0)
- Exchange TABLE(loop1,1),TABLE(newpos,1)
- Next loop1
- Next loop
- For loop=0 To #TABLE_LIMIT-1
- xpos=TABLE(loop,0):ypos.l=TABLE(loop,1)
- trydirection=0:moved=0:length=0
- While moved=0
- If length>=#GRID_COMPLEX-1 Then direction=Rnd(4):length=0
- newxpos=xpos:newypos=ypos:wallxpos=xpos:wallypos=ypos
- Select direction
- Case 0:newxpos-2:wallxpos-1:trydirection|1
- Case 1:newypos-2:wallypos-1:trydirection|2
- Case 2:newxpos+2:wallxpos+1:trydirection|4
- Case 3:newypos+2:wallypos+1:trydirection|8
- End Select
- If (newxpos>0)AND(newxpos<#GRID_WIDTH)
- If (newypos>0)AND(newypos<#GRID_HEIGHT)
- If (GRID(wallxpos,wallypos)=1)AND(GRID(newxpos,newypos)=0)
- GRID(wallxpos,wallypos)=0:GRID(xpos,ypos)=2
- TABLE(tablemax,0)=newxpos:TABLE(tablemax,1)=newypos:tablemax+1
- xpos=newxpos:ypos=newypos:trydirection=0:length+1
- Else
- If trydirection=15
- GRID(xpos,ypos)=2:moved=1
- Else
- direction=Rnd(4)
- End If
- End If
- Else
- direction=Rnd(4)
- End If
- Else
- direction=Rnd(4)
- End If
- Wend
- Next loop
- ;now cleanup grid (we only want 0 + 256 in grid)
- For xloop=0 To #GRID_WIDTH-1
- For yloop=0 To #GRID_HEIGHT-1
- Select GRID(xloop,yloop)
- Case 1:GRID(xloop,yloop)=256
- Default:GRID(xloop,yloop)=0
- End Select
- If Rnd(100)<#GRID_EMPTY
- If (yloop>0)&(yloop<(#GRID_HEIGHT-1))
- If (xloop>0)&(xloop<(#GRID_WIDTH-1)) Then GRID(xloop,yloop)=0
- EndIf
- EndIf
- Next yloop
- Next xloop
- Return
-
- SHOW_GRID:
- ;display it on currently used bitmap
- showscale=8:showcircle=showscale/2 ;:Cls 0
- For xloop=0 To #GRID_WIDTH-1
- xpos=xloop*showscale
- For yloop=0 To #GRID_HEIGHT-1
- ypos=yloop*showscale
- Select GRID(xloop,yloop)
- Case 1:Boxf xpos,ypos,xpos+showscale-1,ypos+showscale-1,0:Boxf xpos+1,ypos+1,xpos+showscale-2,ypos+showscale-2,3
- Case 32:Circlef xpos+showcircle-1,ypos+showcircle-1,showcircle,showcircle,2
- Case 256:Boxf xpos,ypos,xpos+showscale-1,ypos+showscale-1,1
- Default:Boxf xpos,ypos,xpos+showscale-1,ypos+showscale-1,0
- End Select
- Next yloop
- Next xloop
- ; now show bot colours
- ; ResetList stats():USEPATH stats()
- ; While NextItem(stats())
- ; Wend
- Return
-
- SHOW_STATS:
- ResetList stats():USEPATH stats()
- Locate 0,0:ply=0:Format "00000"
- NPrint "Ply Bot Shots Hit TimePerCycle"
- While NextItem(stats())
- mytype=\bottype:hitnum.l=0
- For loop=1 To #BOT_MAX
- hitnum=hitnum+hits(mytype,loop)
- Next loop
- NPrint ply," ",\bottype," ",\shots," ",hitnum," ",\time/#CYCLE_MAX
- ply+1
- Wend
- NPrint ""
- NPrint " Cycles = ",#CYCLE_MAX
- Return
-
- INIT_DISPLAY:
- Screen 0,12,"BlitzBotz V0.1 Test!"
- ScreensBitMap 0,0:BitMapOutput 0
- Return
-
- MAKE_PATH:
- ;makes a single random path through the grid
- xpos=Rnd(((#GRID_WIDTH-1)/2)*2)|1
- ypos=Rnd(((#GRID_HEIGHT-1)/2)*2)|1
- For loop=0 To #GRID_COMPLEX
- length=0:path=0:trydirection=0:direction=Rnd(4)
- While (length<#GRID_COMPLEX)AND(path=0)
- Select direction
- Case 0:Gosub GO_LEFT:trydirection|1
- Case 1:Gosub GO_UP:trydirection|2
- Case 2:Gosub GO_RIGHT:trydirection|4
- Case 3:Gosub GO_DOWN:trydirection|8
- End Select
- If GRID(xpos,ypos)=0
- direction=Rnd(4):If trydirection=15 Then path=1
- Else
- length+1
- Select direction
- Case 0:xpos-2
- Case 1:ypos-2
- Case 2:xpos+2
- Case 3:ypos+2
- End Select
- trydirection=0
- If xpos<1 Then path=1:xpos+2
- If xpos>=#GRID_WIDTH Then path=1:xpos-2
- If ypos<1 Then path=1:ypos+2
- If YPOS>=#GRID_HEIGHT Then path=1:ypos-2
- End If
- Wend
- Next loop
- GRID(xpos,ypos)=2
- Return
-
- GO_LEFT:
- If (xpos-2)>0
- If GRID(xpos-2,ypos)<>2
- GRID(xpos-1,ypos)=0
- GRID(xpos,ypos)=2
- End If
- End If
- Return
-
- GO_RIGHT:
- If (xpos+2)<#GRID_WIDTH
- If GRID(xpos+2,ypos)<>2
- GRID(xpos+1,ypos)=0
- GRID(xpos,ypos)=2
- End If
- End If
- Return
-
- GO_UP:
- If (ypos-2)>0
- If GRID(xpos,ypos-2)<>2
- GRID(xpos,ypos-1)=0
- GRID(xpos,ypos)=2
- End If
- End If
- Return
-
- GO_DOWN:
- If (ypos+2)<#GRID_HEIGHT
- If GRID(xpos,ypos+2)<>2
- GRID(xpos,ypos+1)=0
- GRID(xpos,ypos)=2
- End If
- End If
- Return
-
- ;GRID
- ;
- ; -1 - outside of grid
- ; you can move through this group
- ; 0 - empty square
- ; 1 - shot
- ; 2 -
- ; 4 -
- ; you can't move through this group (reserved for players-bots etc)
- ; 16 -
- ; 32 - bot
- ; 64 -
- ; 128 -
- ; A solid block (impassable stuff.....)
- ; 256 - block
- ;
-
-
-
-